# coding=utf-8
import sys
import time
from function_utils import Global, Human, TableRender, PsUtil


def process_info(interval=2, limit=25, sort_by='mem_percent', reverse=True):
    output = 'PID|USER|PPID|Threads|%CPU|%Mem|RSS|Process-Name'
    infos, sorts = {}, {}

    PsUtil.init()
    mem_total = PsUtil.memory()['total']
    pids = PsUtil.pids()
    proc_cache = {}
    for pid in pids:
        try:
            proc_cache[pid] = (PsUtil.Process(pid, only_cpu=True).cpu_times(), time.time())
        except:
            continue
    time.sleep(interval)

    for pid in pids:
        try:
            process = PsUtil.Process(pid)
            cpu_times = process.cpu_times()
            last_cpus = proc_cache[pid]
            cpu_percent ='%.1f' % (((cpu_times[0] - last_cpus[0][0]) + (cpu_times[1] - last_cpus[0][1])) /
                                   (time.time() - last_cpus[1]) * 100)
            ppid = '%s' % process.ppid()
            threads = '%s' % process.num_threads()
            memory = Human.size(process.memory())
            mem_percent = '%.1f' % process.mem_percent(mem_total)
            proc_name = process.name()

            infos[pid] = (str(pid),
                          process.username(),
                          ppid,
                          threads,
                          cpu_percent,
                          mem_percent,
                          memory,
                          proc_name,
                          )
            sorts[pid] = float(eval(sort_by.lower()))
        except Exception:
            continue

    news = sorted(sorts.items(), key=lambda x: x[1], reverse=reverse)
    for i, item in enumerate(news):
        if i > limit: break
        output = '%s\n%s' % (output, '|'.join(infos[item[0]]))
    return TableRender(output)


def write_widgets_value(value):
    data = [
        {"MultiInfoText": value},
        {},
        {}
    ]
    Global.values_write(data)
    Global.report_info(100)


def parse_widgets_value(data):
    values = Global.values_parse(data)
    (types, value), = values[1].items()
    sort_by = 'mem_percent'
    reverse = True
    if types == 'Combobox':
        if value == 'Mem':
            sort_by = 'mem_percent'
        elif value == 'CPU':
            sort_by = 'cpu_percent'
        elif value == 'Threads':
            sort_by = 'threads'
        elif value == 'PID':
            sort_by = 'pid'
    (types, value), = values[2].items()
    if types == 'Combobox':
        if value == 'Yes':
            reverse = True
        elif value == 'No':
            reverse = False
    return sort_by, reverse


def main():
    sort_by = 'mem_percent'
    reverse = True
    if sys.argv[1] == 'start':
        sort_by, reverse = parse_widgets_value(sys.argv[2])
    write_widgets_value(process_info(sort_by=sort_by, reverse=reverse))


if __name__ == '__main__':
    main()
